package com.itphy.conf;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.client.RestTemplate;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class CommonConfig {
    private static final Logger logger = LoggerFactory.getLogger(CommonConfig.class);

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    public RabbitTemplate rabbitTemplate2(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate=new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback((correlationData,ack,cause)->{
            if(ack){
                logger.info("1:消息推送 exchange 成功!");
            }else {
                logger.info("1:消息推送 exchange 失敗!",cause);
            }
        });
        rabbitTemplate.setReturnCallback((message,replayCode,replyText,exchange,routingKey)->{
            String correlationId = message.getMessageProperties().getCorrelationId();
            logger.info("2:消息推送 queue 失敗",message);
        });
        return rabbitTemplate;
    }

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
        return redisTemplate;
    }

    /**
     * 声明死信队列
     * @return DirectExchange
     */
//    @Bean
//    public DirectExchange dlxExchange() {
//        return new DirectExchange("dlxExchange");
//    }
//
//    @Bean
//    public Queue dlxQueue(){
//        return new Queue("dlxQueue");
//    }
//
//    @Bean
//    public Binding binding() {
//        return BindingBuilder.bind(dlxQueue())
//                .to(dlxExchange())
//                .with("dlxRoutingKey");
//    }

    @Bean
    public Queue oneDirectQueue() {
//        Map<String,Object> arguments = new HashMap<>(2);
//        arguments.put("x-dead-letter-exchange",dlxExchange());
//        arguments.put("x-dead-letter-routing-key","dlxRoutingKey");
//        return new Queue("oneDirectQueue",true,false,false,arguments);
        return new Queue("oneDirectQueue",true);
    }

    @Bean
    public Queue queue() {
        return new Queue("all",true);
    }

    @Bean
    public Queue twoDirectQueue() {
        return new Queue("twoDirectQueue",true);
    }

    @Bean
    TopicExchange oneTopicExchange() {
        return new TopicExchange("oneTopicExchange",true,false);
    }

    @Bean
    FanoutExchange fanoutExchange(){
        return new FanoutExchange("fanoutExchange");
    }

    @Bean
    DirectExchange twoDirectExchange() {
        return new DirectExchange("twoDirectExchange");
    }

    @Bean
    DirectExchange oneDirectExchange() {
        return new DirectExchange("oneDirectExchange");
    }

    @Bean
    DirectExchange testDirectExchange() {
        return new DirectExchange("testDirectExchange",true,false);
    }

    @Bean
    TopicExchange testTopicExchange() {
        return new TopicExchange("testDirectExchange",true,false);
    }

    @Bean
    Binding bindingDirect(@Qualifier("oneDirectQueue") Queue queue,@Qualifier("testDirectExchange") DirectExchange directExchange) {
        return BindingBuilder.bind(queue).to(directExchange).with("route1");
    }

//    @Bean
//    Binding bindingDirect2() {
//        return BindingBuilder.bind(oneDirectQueue()).to(testDirectExchange()).with("route2");
//    }

    @Bean
    Binding bindingDirect3() {
        return BindingBuilder.bind(oneDirectQueue()).to(oneTopicExchange()).with("#");
    }

    @Bean
    Binding bindingDirectAll() {
        return BindingBuilder.bind(queue()).to(fanoutExchange());
    }
}
